<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    /* 
    - 变量提升(`变量声明提升`)
      - 变量声明语句会提升到当前作用域的最前面执行
      - 在变量声明语句之前, 就可以访问到这个变量(undefined)
    - 函数提升(`函数声明提升`)
      - 函数声明语句提升到当前作用域的最前面执行
      - 在函数声明语句之前, 就可以执行该函数
    - 原因: 简单来说就是在执行全局代码和函数前会进行`预解析/处理`
      - 将var变量声明放在最前面执行
      - 将function函数声明放在最前面执行
    - 注意
      - const / let / class 没有提升
      - var 变量 / function 函数声明 才有提升
    */

    /* 
    var a
    function fn() {
      
    }

    console.log(a) 
    a = 3
    */
    
    fn()
    console.log(a) // undefined
    console.log(fn2) // undefined
    fn2()

    var a = 3
    function fn() { // 函数声明  会提升
      
      var b = 3
      function fn2() {
        
      }
    }
    var fn2 = function () { // 函数表达式  不会提升
      
    }

    (function () {
      
    })() // IIFE  立即执行函数表达式 Function Expression

    

    // 函数表达式 定义函数
    var a6 = function () {};

    (function () {})();  // 立即调用函数表达式 IIFE

    // function () {}  这是一个表达式, 不能单独存在, 必须与其它运算结果起来形成一条语句

    // fn(3)
    // 表达式: 数据值  3/'abc'/true/{} /    值与运算的组合  3 + 1   变量  变量与运算的组合
    // {{表达式}}  {{3}}  {{a}}
  </script>
</body>
</html>